/**
 * 数据库结构表述
 */
export type IDBSchema = Array<IDBSchemaStore>

/**
 * 集合描述
 */
export type IDBSchemaStore = {
  // 表名, 也称集合名
  storeName: string
  // 主键索引
  primaryKey: {
    // 主键路径, 推荐写数字类型的 id.
    // 注意: 主键设置好后不得变更
    keyPath: string
    // 键生成器是否自增. 默认 false
    autoIncrement?: boolean
  }
  /** 表结构信息 */
  infos: Array<IDBSchemaStoreInfo>
  // 其他索引以及复合索引
  indexes?: Array<IDBSchemaStoreIndex>
}

/**
 * 表里的索引
 */
export type IDBSchemaStoreIndex = {
  // 索引名
  keyName: string
  // 索引路径, 也就是对应的具体键. keyPath: 'time', 复合索引可以 keyPath: ['iid', 'time'],
  keyPath?: string | string[]
  // 是否索引的值唯一. 默认 false
  unique?: boolean
  // 是否为复合索引. 默认 false
  // 假设你有一个存储书籍的对象存储，
  // 每本书有一个名为 "authors" 的属性，它是一个数组，包含了多个作者。
  // 如果你想要能够根据作者名进行检索，
  // 你可以创建一个 MultiEntry 为 true 的索引，
  // 这样每个作者的名字都会被索引，而不仅仅是整个数组。
  // 这样就可以通过作者名来检索包含该作者的所有书籍。
  multiEntry?: boolean
}

/**
 * 表里的字段类型
 */
export const enum IDBSchemaStoreInfoType {
  IDB_SCHEMA_ITEM_INFO_TYPE_NUMBER = 1,
  IDB_SCHEMA_ITEM_INFO_TYPE_STRING = 2,
  IDB_SCHEMA_ITEM_INFO_TYPE_BOOLEAN = 3,
  IDB_SCHEMA_ITEM_INFO_TYPE_DATE = 4,
  IDB_SCHEMA_ITEM_INFO_TYPE_ARRAY = 5,
  IDB_SCHEMA_ITEM_INFO_TYPE_OBJECT = 6
}

/**
 * 表里的字段信息
 */
export type IDBSchemaStoreInfo = {
  // 字段名
  name: string
  // 字段类型
  type: IDBSchemaStoreInfoType
  // 默认值
  default?: number | string | boolean | Date
}

/**
 * 根据表结构推回来的数据类型
 */
export type IDBDataType = {
  [K in IDBSchemaStoreInfo['name']]: IDBDataTypeGeneric<Extract<IDBSchemaStoreInfo, { name: K }>['type']>
}

/**
 * 数据类型泛型. 用于从
 * {
 *   name: 'text',
 *   type: IDBSchemaStoreInfoType.IDB_SCHEMA_ITEM_INFO_TYPE_STRING
 * }
 * 反推出类型
 * {
 *   text: string
 * }
 */
type IDBDataTypeGeneric<T extends IDBSchemaStoreInfoType> = T extends IDBSchemaStoreInfoType.IDB_SCHEMA_ITEM_INFO_TYPE_STRING
  ? string
  : T extends IDBSchemaStoreInfoType.IDB_SCHEMA_ITEM_INFO_TYPE_NUMBER
  ? number
  : T extends IDBSchemaStoreInfoType.IDB_SCHEMA_ITEM_INFO_TYPE_BOOLEAN
  ? boolean
  : T extends IDBSchemaStoreInfoType.IDB_SCHEMA_ITEM_INFO_TYPE_DATE
  ? Date
  : T extends IDBSchemaStoreInfoType.IDB_SCHEMA_ITEM_INFO_TYPE_ARRAY
  ? Array<any>
  : T extends IDBSchemaStoreInfoType.IDB_SCHEMA_ITEM_INFO_TYPE_OBJECT
  ? any
  : any

export type IDBStoreBulkDeleteOptions = {
  /** 索引名, 必须有索引, 哪怕索引传的是主键 id. */
  keyName?: string
  /** 索引值 */
  value?: string | number
  /** 索引值下限 */
  lower?: number | Array<string | number>
  /** 索引值上限 */
  upper?: number | Array<string | number>
  /** 索引值下限是否开区间. 默认 false */
  lowerOpen?: boolean
  /** 索引上限是否开区间. 默认 false */
  upperOpen?: boolean
  /** 其他条件之过滤器, 匹配在这个过滤器返回 true 的值. */
  filter?: (data: IDBDataType) => boolean
}

export type IDBStoreBulkReadOptions = {
  /** 索引名, 必须有索引, 哪怕索引传的是主键 id. */
  keyName?: string
  /** 索引值 */
  value?: string | number
  /** 索引值下限 */
  lower?: number | Array<string | number>
  /** 索引值上限 */
  upper?: number | Array<string | number>
  /** 索引值下限是否开区间. 默认 false */
  lowerOpen?: boolean
  /** 索引上限是否开区间. 默认 false */
  upperOpen?: boolean
  /**
   * 分页条件-偏移量-当前到第多少条
   */
  // offset?: number | string
  /**
   * 分页条件-页码
   */
  // limit?: number
  /** 其他条件之过滤器, 匹配在这个过滤器返回 true 的值. */
  filter?: (data: IDBDataType) => boolean
}
